import React, { useEffect } from 'react';
import styles from './style.less';
import { useSetState, useDebounceFn } from 'ahooks';
import { Button, Input, Row, Col, Space, Spin, Modal } from 'antd';
import styled from 'styled-components';

import { TRAlert, TRButton, TRDefault, PLoading } from '#/components';
import { HttpCode } from '#/utils/contacts.js';
import emitter from '#/utils/events';
import { mqttCentre } from '#/utils/mqttCentre';
import renovate from '#/utils/renovate';

import { getDetaiData, getPointAdjustment, pointDistribution } from '../../services';
import { MQTT_SHORT } from '../../helper';
import BaseTable from '../BaseTable/baseTableList';
import Charts from '../Charts';
import { COLUMN, detailData, onTimeList, detailDataList, scaleDataList } from './helper';

const BoxWrap = styled.div`
  background-color: var(--bg-main);
  padding: 10px 14px;
  margin: 24px 24px 10px;
`;

let scalePoint = 0,
  selectStation = '',
  ineDataTime = '';
export default function SuperShort({
  dataTime,
  selectStationId,
  onGetData,
  buttonPermissions,
  maxinLoading,
  maxinLoadingFun,
}) {
  let timer = null;
  const [state, setState] = useSetState({
    data: [],
    columns: [],
    columnsText: [],
    dataSource: [],
    hasEdit: false,
    signPoint: 'A-1',
    signPointArr: ['A-1', 'B-1'],
    dataSourceText: [],
    inputValue: '',
    clipboardData: [],
    hasDataArr: {},
    isEmpty: true,
    spinning: false,
    stationId: selectStationId,
    scaleArr: 1,
    contrastDataSource: [],
    mattString: false,
  });
  let clinHeight = document.body.clientHeight > 700 ? 800 : 790;
  useEffect(() => {
    window.addEventListener('resize', resizeHelper.run);
    emitter.addListener('onChangeMnue', resizeHelper.run);
    // 暂时注销
    // mqttCentre.connect('mosquitto', 'Mosquitto.com', 'wss://transaction.gw-ams.com:8083');
    capacityMqtt();
    return () => {
      // mqttCentre.end();
      window.removeEventListener('resize', resizeHelper.run);
      emitter.removeListener('onChangeMnue', resizeHelper.run);
      scalePoint = null;
      selectStation = null;
      ineDataTime = null;
      clearTimeout(timer);
      timer = null;
    };
  }, []);

  useEffect(async () => {
    capacityMqtt();
  }, [state.hasEdit]);

  const resizeHelper = useDebounceFn(
    () => {
      clinHeight = document.body.clientHeight > 700 ? 800 : 790;
    },
    { wait: 300 },
  );

  useEffect(async () => {
    selectStation = selectStationId;
    state.stationId = selectStationId;
    const dataTimeArr = await fetchData();
    const datas = await detaiData(dataTimeArr, dataTime);
    renovate.isRenovate = false;
    state.columnsLight = dataTimeArr;
    ineDataTime = dataTimeArr;
    setState({
      columnsText: datas,
      columnsLight: dataTimeArr,
      stationId: selectStationId,
    });
  }, [selectStationId]);

  useEffect(async () => {
    if (!state.mattString) return;
    const { data } = state.mattString;
    if (data.includes(selectStation)) {
      let dataTimeArr;
      if (state.hasEdit) {
        dataTimeArr = await getPointAdjustmentList(scalePoint);
      } else {
        dataTimeArr = await fetchData();
      }
      const datas = await detaiData(dataTimeArr, dataTime);
      ineDataTime = dataTimeArr;
      state.columnsLight = dataTimeArr;
      setState({
        columnsText: datas,
        columnsLight: dataTimeArr,
        mattString: false,
      });
      return;
    }
  }, [state.mattString]);
  const capacityMqtt = () => {
    Object.entries(MQTT_SHORT).map(([key, topic]) => {
      mqttCentre.subscribe(key, topic, (data) => {
        let obj = {
          key,
          data,
        };
        setState({ mattString: obj });
      });
    });
  };

  useEffect(async () => {
    const dataTimeArr = await getPointAdjustmentList(scalePoint);
    const datas = await detaiData(dataTimeArr, dataTime);
    state.columnsLight = dataTimeArr;
    ineDataTime = dataTimeArr;
    setState({
      columnsText: datas,
      columnsLight: dataTimeArr,
    });
  }, [JSON.stringify(dataTime), state.signPointArr]);

  useEffect(() => {
    getColumn();
  }, [state.hasEdit, state.signPoint]);

  const detaiData = async (dataTimeArr, nowData) => {
    const { scaleArr } = state;
    const [startTime, endTime] = nowData;
    const beginDate = startTime.format('YYYY-MM-DD'),
      endData = endTime.format('YYYY-MM-DD');
    const datas = onTimeList(beginDate, endData, dataTimeArr, scaleArr);
    return datas;
  };

  const onBlurData = (_value, record) => {
    const { dataSource, signPoint, beginDate, endData } = state;
    const _dataSource = dataSource.map((item) => {
      if (record.id === item.id) {
        if (item.id === signPoint) {
          scalePoint = (_value === '' ? item.scale : _value) / 100;
          const dataSourceTexts = scaleDataList(
            state.contrastDataSource,
            beginDate,
            endData,
            ineDataTime,
            (_value === '' ? item.scale : _value) / 100,
          );
          setState({ dataSourceText: dataSourceTexts });
        }
        return {
          ...item,
          scale: _value === '' ? item.scale : _value,
        };
      } else {
        return {
          ...item,
        };
      }
    });
    state.dataSource = _dataSource;
    setState({
      dataSource: _dataSource,
    });
  };

  const getColumn = () => {
    const { hasEdit } = state;
    const columns = COLUMN.map((item) => {
      return {
        ...item,
        render: (text, record) => {
          if (item.code === 'scale' && hasEdit) {
            return (
              <div className={styles.content_input}>
                <Input
                  value={text}
                  size="small"
                  onChange={(value) => {
                    onChange(value, record);
                  }}
                  onBlur={(e) => {
                    onBlurData(e.target.value, record);
                  }}
                />
              </div>
            );
          }
          if (item.code === 'point') {
            return (
              <div
                className={styles.content_point}
                onClick={() => {
                  onChangePoint(record);
                }}
              >
                <span className={state.signPoint === record.id ? styles.sign_point : ''}>
                  {text}
                </span>
              </div>
            );
          }
          return <div className={styles.content_text}>{text}</div>;
        },
      };
    });
    setState({
      columns: columns,
    });
  };

  const onChange = (e, record) => {
    const { dataSource } = state;
    let _value = e?.target?.value;
    const reg = /^(\d+)(\.\d{0,3})?$/;
    if (reg.test(_value) || _value === '') {
      state.scaleArr = (_value ?? 0) / 100;
      const _dataSource = dataSource.map((item) => {
        if (item.id === record.id) {
          return {
            ...item,
            scale: _value ?? item.scale,
          };
        }
        return {
          ...item,
        };
      });
      renovate.isRenovate = true;
      setState({
        inputValue: _value,
        dataSource: _dataSource,
      });
    }
  };

  const onChangePoint = async (item) => {
    const pointArr = (item?.id || 'A-1').split('-');
    scalePoint = item.scale / 100;
    const scalePointlist = [`A-${pointArr[1]}`, `B-${pointArr[1]}`];
    state.signPointArr = scalePointlist;
    state.signPoint = item?.id || 'A-1';
    state.scaleArr = scalePoint;
    setState({
      spinning: true,
      signPoint: item?.id || 'A-1',
      scaleArr: item.scale / 100,
      signPointArr: scalePointlist,
    });
  };

  const fetchData = async () => {
    setState({ spinning: true, hasEdit: false });
    const req = await getPointAdjustment({
      stationId: selectStation,
    });
    if (req?.statusCode === HttpCode.SUCCESS) {
      if ((req.rateList ?? []).length === 0) {
        maxinLoadingFun(false);
        setState({ spinning: false, isEmpty: true });
        return false;
      }
      const dataSource = detailData(req.rateList ?? []);
      const ind = _.findIndex(state.dataSource, { id: state.signPoint });
      scalePoint = req?.rateList?.[ind] || 1;
      const dateStr = await getPointAdjustmentList(req?.rateList?.[ind] || 1);
      setState({
        data: req.rateList,
        dataSource: dataSource,
      });
      return dateStr;
    } else {
      maxinLoadingFun(false);
      setState({ spinning: false });
    }
  };

  const getPointAdjustmentList = async (scaleArr = state.scaleArr) => {
    const { signPointArr } = state;
    const [startTime, endTime] = dataTime;
    const beginDate = startTime.format('YYYY-MM-DD'),
      endData = endTime.format('YYYY-MM-DD');
    let res = await getDetaiData({
      beginDate: startTime.format('YYYY-MM-DD'),
      endDate: endTime.format('YYYY-MM-DD'),
      points: signPointArr,
      stationId: selectStation,
    });
    if (res?.statusCode === HttpCode.SUCCESS) {
      const shortPointData =
        Object.values(res?.shortPointData ?? {}).length === 0 ? [] : res?.shortPointData;
      const { dataSourceList, dateStr = '' } = detailDataList(shortPointData, scaleArr);
      state.contrastDataSource = dataSourceList;
      isEmptyJudge(dataSourceList);
      const dataSourceTexts = scaleDataList(dataSourceList, beginDate, endData, dateStr, scaleArr);
      maxinLoadingFun(false);
      setState({
        dataSourceText: dataSourceTexts,
        contrastDataSource: dataSourceList,
        beginDate,
        endData,
        spinning: false,
      });
      return dateStr;
    }
  };

  const isEmptyJudge = (data) => {
    const dataArr = data.filter((i) => {
      return _.compact(Object.values(i)).length > 5;
    });
    setState({
      isEmpty: dataArr.length === 0,
    });
  };
  const handleOk = useDebounceFn(
    async () => {
      const { dataSource, data } = state;
      const beforeRateList = data.map((i) => {
        return (i * 100).toFixed(3);
      });
      let afterRateList = [];
      const afterRealRateList = dataSource.map((i) => {
        const sum = i.scale / 100;
        afterRateList.push(i.scale);
        return sum;
      });
      PLoading.show('数据处理中...');
      const res = await pointDistribution({
        beforeRateList,
        afterRateList,
        afterRealRateList,
        stationId: selectStationId,
        hasEdit: false,
      });
      PLoading.dismiss();

      if (res && res.statusCode === HttpCode.SUCCESS) {
        renovate.isRenovate = false;
        const modal = Modal.success({
          content: res?.message || '下发成功',
          centered: true,
          onOk: () => {
            clearTimeout(timer);
          },
        });
        timer = setTimeout(() => {
          modal.destroy();
        }, 5000);
      } else {
        TRAlert.error(res?.message || '下发失败');
      }
    },
    { wait: 300 },
  );

  const onHasEdit = () => {
    state.hasEdit = true;
    setState({
      hasEdit: true,
    });
  };

  const onCancel = async () => {
    const obj = await TRAlert.show('当前工作将不被保存，继续执行此操作？');
    if (obj.index === 1) {
      renovate.isRenovate = false;
      const dataTimeArr = await fetchData();
      const datas = await detaiData(dataTimeArr, dataTime);
      renovate.isRenovate = false;
      state.stationId = selectStationId;
      ineDataTime = dataTimeArr;
      setState({
        columnsText: datas,
        columnsLight: dataTimeArr,
      });
      setState({
        hasEdit: false,
      });
    }
  };
  return (
    <BoxWrap>
      <Spin spinning={state.spinning || maxinLoading}>
        <div className={styles.container} style={{ height: `${clinHeight}px` }}>
          <Row>
            <Col span={21}>
              {state.isEmpty ? (
                <div className={styles.empty}>
                  <TRDefault type="emptysm" />
                </div>
              ) : (
                <Charts
                  config={state.dataSourceText}
                  columnsText={state.columnsText}
                  signPoint={state.signPoint}
                  onGetData={onGetData}
                />
              )}
            </Col>
            <Col span={3}>
              {state.dataSource.length > 0 ? (
                <div>
                  <div className={styles.content_btn}>
                    {state.hasEdit ? (
                      <Space>
                        <Button onClick={onCancel}>取消</Button> {' '}
                        <TRButton
                          menuCode="ChaoDuanQiYuCeTiaoZhengXiaFa"
                          type="primary"
                          buttonPermissions={buttonPermissions}
                          onClick={handleOk.run} // darkStyle={false}
                        >
                          确定
                        </TRButton>
                      </Space>
                    ) : (
                      <Button type="primary" onClick={onHasEdit}>
                        编辑
                      </Button>
                    )}
                  </div>
                  <div style={{ border: '1px solid #434343', borderRadius: ' 5px' }}>
                    <BaseTable
                      columns={state.columns}
                      dataSource={state.dataSource}
                      styles={{
                        '--row-height': '30px',
                        '--bgcolor': '#222629',
                        '--header-bgcolor': '#353638',
                        '--cell-border': '1px solid #434343',
                        '--header-cell-border': '1px solid #434343',
                      }}
                    />
                  </div>
                </div>
              ) : (
                ''
              )}
            </Col>
          </Row>
          <div className={styles.containerBottom}>
            {state.isEmpty ? (
              ''
            ) : (
              <BaseTable
                columns={state.columnsText}
                dataSource={state.dataSourceText}
                styles={{
                  '--row-height': '30px',
                  '--bgcolor': '#222629',
                  '--header-bgcolor': '#353638',
                  '--cell-border': '1px solid #434343',
                  '--header-cell-border': '1px solid #434343',
                }}
              />
            )}
          </div>
        </div>
      </Spin>
    </BoxWrap>
  );
}
